Securing Connections
MySQL supports SSL/TLS (Secure Sockets Layer / Transport Layer Security) to encrypt client-server communication. By default, MySQL connections are plaintext, meaning data (including passwords) can be intercepted if transmitted over a network. Using SSL/TLS ensures:
- Encryption → Protects data in transit from eavesdropping.
- Authentication → Ensures the client is connecting to the right server.
- Integrity → Prevents data tampering.
How SSL/TLS Works in MySQL
- Server and Client Certificates → Both server and client can use X.509 certificates for authentication.
- Handshake → When the client connects, it negotiates encryption parameters with the server.
- Encrypted Session → All subsequent communication is encrypted.
Enabling SSL/TLS in MySQL
Step 1: Generate Certificates & Keys
You need:
- CA certificate (
ca-cert.pem) - Server certificate (
server-cert.pem) and key (server-key.pem) - Client certificate (
client-cert.pem) and key (client-key.pem)
Place all certificates in a folder on Windows, e.g.:
C:\Users\USER\mysql-certs
Tip: You can generate certificates either manually using OpenSSL or let MySQL generate them automatically using
mysql_ssl_rsa_setup.exe.
Step 2: Start MySQL Docker Container with SSL
docker run --name mysql-secure -e MYSQL_ROOT_PASSWORD=my-secret-pw -v "C:\Users\USER\mysql-certs:/etc/mysql/ssl" -p 3306:3306 -d mysql:latest --ssl-ca=/etc/mysql/ssl/ca-cert.pem --ssl-cert=/etc/mysql/ssl/server-cert.pem --ssl-key=/etc/mysql/ssl/server-key.pem
-v "C:\Users\USER\mysql-certs:/etc/mysql/ssl"→ mounts cert folder into container--ssl-ca,--ssl-cert,--ssl-key→ tell MySQL server where the certificates are-p 3306:3306→ exposes MySQL port for TCP connections
Step 3: Enter MySQL Container
docker exec -it mysql-secure mysql -u root -p
Check SSL-related variables:
SHOW VARIABLES LIKE 'ssl_%';
You should see paths pointing to /etc/mysql/ssl/...
Note:
have_sslis deprecated in MySQL 8 and may be empty — ignore it.
Step 4: Create SSL-Required Users
SSL-only user
CREATE USER 'secure_user'@'%' IDENTIFIED BY 'StrongPass123' REQUIRE SSL;
GRANT ALL PRIVILEGES ON *.* TO 'secure_user'@'%';
FLUSH PRIVILEGES;
This user cannot connect without SSL/TLS. Certificate-based authentication (optional)
CREATE USER 'cert_user'@'%' REQUIRE X509;
GRANT ALL PRIVILEGES ON *.* TO 'cert_user'@'%';
FLUSH PRIVILEGES;
This user requires the client to present a valid certificate signed by your CA.
Step 5: Connect from Client Using SSL
Important: SSL works only over TCP. Do not connect via Unix socket inside the same container.
Connect from Windows host
mysql -u secure_user -p --ssl-mode=REQUIRED --ssl-ca=C:\Users\USER\mysql-certs\ca-cert.pem --ssl-cert=C:\Users\USER\mysql-certs\client-cert.pem --ssl-key=C:\Users\USER\mysql-certs\client-key.pem -h 127.0.0.1 -P 3306
Connect from a separate Docker client container
docker run -it --rm -v C:\Users\USER\mysql-certs:/certs mysql:latest bash
Inside the container
mysql -u secure_user -p --ssl-mode=REQUIRED --ssl-ca=/certs/ca-cert.pem --ssl-cert=/certs/client-cert.pem --ssl-key=/certs/client-key.pem -h host.docker.internal -P 3306
Step 6: Verify SSL Connection
Inside MySQL
SHOW STATUS LIKE 'Ssl_cipher';
Expeceted Output:
+---------------+----------------------+
| Variable_name | Value |
+---------------+----------------------+
| Ssl_cipher | TLS_AES_256_GCM_SHA384 |
+---------------+----------------------+
If empty → SSL is not being used (likely you connected via socket, not TCP).
Step 7: Test Non-SSL Connection Failure
Try connecting without SSL:
mysql -u secure_user -p -h 127.0.0.1 -P 3306
Should fail:
ERROR 1045 (28000): SSL connection is required
This confirms the SSL requirement is enforced.
Step 8: Optional – Verify Certificate Authentication
For cert_user:
mysql -u cert_user -p --ssl-mode=REQUIRED --ssl-ca=C:\Users\USER\mysql-certs\ca-cert.pem --ssl-cert=C:\Users\USER\mysql-certs\client-cert.pem --ssl-key=C:\Users\USER\mysql-certs\client-key.pem -h 127.0.0.1 -P 3306
Only works if the client presents the certificate signed by the CA.